<?php
namespace App\Service\VendorClient\Shopqdsd;

use App\Service\Code\Normal;
use App\Service\BaseService;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;

/**
 * 青岛双递 SDK 轩辕供应链
 * @author chenyun
 */
class ShopqdsdApiClient extends BaseService {
    private   $account  = 'shopqdsd';
    protected $config;
    protected $RouteMap = [
        'createOrder' => 'xuanyuan.order.push',
        'cancelOrder' => 'xuanyuan.order.cancel',
    ];

    /**
     * 初始参数
     * @param array $collection
     */
    public function __construct($apiBody = []) {
        $this->config = $apiBody;
    }

    /**
     * 创建订单
     */
    public function createOrder($params = []) {
        ini_set('serialize_precision', 16);

        if (empty($params['supplierOrder']) || empty($params['orderGoods']) || empty($params['order']) || empty($params['binfo'])) {
            return Normal::returnCode(Normal::FAIL, "except param supplierOrder or orderGoods or order or binfo");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        $order     = $params['order'];
        $binfo     = $params['binfo'];
        //运费
        $deliver_money = $orderInfo['deliver_money'];
        //商品下单组
        $orderGoods = [];
        $productAmt = $TaxAmt = 0;
        foreach ($params['orderGoods'] as $key => $item) {
            //卖价
            $price = $item['price'];
            //商品购买规格数量
            $spec_num = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity = $item['quantity'];
            //实际购买数量
            $buyAcount = $spec_num * $quantity;
            //如果商品除不尽，得多取以为，减去实际金额为折扣，折扣不能为负数
            if ($key == 0) {
                $singleDeliveryMoney = bcdiv((string)$deliver_money, (string)$quantity, 3);
                $singleDeliveryMoney = bcmul((string)$singleDeliveryMoney, (string)100, 1);
                $singleDeliveryMoney = bcdiv((string)ceil($singleDeliveryMoney), (string)100, 2);
                $price               = bcadd((string)$price, (string)$singleDeliveryMoney, 2);
            }
            //单个商品价格
            $singleGoodsPrice = bcdiv((string)$price, (string)$spec_num, 3);
            $singleGoodsPrice = ceil(bcmul((string)$singleGoodsPrice, '100', 1));
            $singleGoodsPrice = bcdiv((string)$singleGoodsPrice, '100', 2);
            $totalGoods       = bcmul((string)$singleGoodsPrice, (string)$buyAcount, 2);
            //含税税率
            $tax_rate = bcadd('1', (string)$item['tax_rate'], 4);
            //不含税价格
            $not_tax_price = bcdiv((string)$singleGoodsPrice, $tax_rate, 3);
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price = ceil(bcmul((string)$not_tax_price, '100', 1));
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price = bcdiv((string)$not_tax_price, '100', 2);

            //税金
            $singleGoodsTax = bcsub((string)$singleGoodsPrice, (string)$not_tax_price, 2);

            //单个商品总税金
            $totalGoodsTax = bcmul($singleGoodsTax, (string)$buyAcount, 2);

            //单个商品总不含税价格
            $totalGoods = bcmul((string)$not_tax_price, (string)$buyAcount, 2);
            //商品组
            $orderGoods[] = [
                'gname'      => $item['goods_name'],
                'gnum'       => (string)($key + 1),
                'itemNo'     => $item['supplier_skucode'],
                'qty'        => (string)$buyAcount,
                'price'      => (string)$not_tax_price,//不含税单价
                'taxPrice'   => $singleGoodsPrice,//含税单价
                'totalPrice' => $totalGoods,//不含税总价
            ];

            $productAmt = bcadd((string)$productAmt, $totalGoods, 2);
            $TaxAmt     = bcadd((string)$TaxAmt, $totalGoodsTax, 2);
        }
        //实际下单金额
        $real_total_money = $orderInfo['real_total_money'];
        //订单总金额 = 含税商品总金额 + 运费 - 优惠金额
        $ActualPaidAmt = bcadd((string)$productAmt, (string)$TaxAmt, 2);
        //优惠金额
        $discount_money = bcsub($ActualPaidAmt, $real_total_money, 2);
        //下单支付的时候支付信息
        $apply_extends = @json_decode($orderInfo['apply_extends'], true);
        //订单时间
        $order_time = $orderInfo['cd'] ? date('Y-m-d H:i:s', $orderInfo['cd']) : date('Y-m-d H:i:s', time());
        //支付时间
        $pay_time = isset($order['payTime']) && !empty($order['payTime']) ? date('Y-m-d H:i:s', $order['payTime']) : date('Y-m-d H:i:s', time());
        //支付公司和电商平台
        $payCommanyCode = isset($apply_extends['payCommanyCode']) && !empty($apply_extends['payCommanyCode']) ? $apply_extends['payCommanyCode'] : '';
        $payCommanyCode = isset($order['payCommanyCode']) && !empty($order['payCommanyCode']) ? $order['payCommanyCode'] : $payCommanyCode;
        $payCommanyName = isset($apply_extends['payCommanyName']) && !empty($apply_extends['payCommanyName']) ? $apply_extends['payCommanyName'] : '';
        $payCommanyName = isset($order['payCommanyName']) && !empty($order['payCommanyName']) ? $order['payCommanyName'] : $payCommanyName;
        $paySerial      = isset($apply_extends['paySerial']) && !empty($apply_extends['paySerial']) ? $apply_extends['paySerial'] : '';
        $paySerial      = isset($order['paySerial']) && !empty($order['paySerial']) ? $order['paySerial'] : $paySerial;
        $enterpriseNum  = isset($apply_extends['enterpriseNum']) && !empty($apply_extends['enterpriseNum']) ? $apply_extends['enterpriseNum'] : '';
        $enterpriseNum  = isset($order['enterpriseNum']) && !empty($order['enterpriseNum']) ? $order['enterpriseNum'] : $enterpriseNum;
        $enterpriseName = isset($apply_extends['enterpriseName']) && !empty($apply_extends['enterpriseName']) ? $apply_extends['enterpriseName'] : '';
        $enterpriseName = isset($order['enterpriseName']) && !empty($order['enterpriseName']) ? $order['enterpriseName'] : $enterpriseName;

        //创建订单数据
        $data         = [
            "orderNo"          => $orderInfo['supplier_dsn'],
            "createTime"       => $order_time,
            "platformId"       => $this->config["platformId"],
            "shopName"         => $this->config["shopName"],
            "orderType"        => "1",
            "cebOrderNo"       => $orderInfo['supplier_dsn'],
            "payTransactionId" => $paySerial,
            // "payMode"          => "微信支付",
            "payMode"          => $payCommanyName,
            "payTime"          => $pay_time,
            "totalAmount"      => $ActualPaidAmt,
            "goodsValue"       => $productAmt,
            "freight"          => "0.00",
            "discount"         => $discount_money > 0 ? $discount_money : '0.00',
            "taxTotal"         => (string)$TaxAmt,
            "actualPaid"       => (string)$real_total_money,
            "buyerWords"       => (string)(!empty($orderInfo["order_remark"]) ? $orderInfo["order_remark"] : ""),
            "ebpName"          => $enterpriseName,
            "ebpCode"          => $enterpriseNum,
            "buyerRegNo"       => $orderInfo['buyer_phone'],
            "buyerName"        => $orderInfo['buyer_realname'],
            "buyerCardType"    => "1",
            "buyerCard"        => $orderInfo['buyer_idcard'],
            "buyerPhone"       => $orderInfo['buyer_phone'],
            "consName"         => $orderInfo['receive_name'],
            "consTelephone"    => $orderInfo['recveive_phone'],
            "consProvice"      => $orderInfo['province'],
            "consCity"         => $orderInfo['city'],
            "consTown"         => $orderInfo['district'],
            "consDetail"       => $orderInfo['receive_address'],
            "orderGoods"       => $orderGoods,
            "appKey"           => $this->config['appKey'],
            "version"          => $this->config['version'],
            "timestamp"        => date("Y-m-d H:i:s", time()),
            "method"           => $this->RouteMap["createOrder"],
        ];
        $requestParam = [
            'method' => 'createOrder',
            'data'   => $data
        ];
        return $this->execute($requestParam);
    }

    /**
     * 获取取消订单
     */
    public function cancelOrder($params = []) {
        if (empty($params['supplierOrder'])) {
            return Normal::returnCode(Normal::FAIL, "except param supplierOrder ");
        }
        //组装订单参数
        $orderInfo    = $params['supplierOrder'];
        $order        = $params['order'];
        $data         = [
            'orderNo'    => $orderInfo['supplier_dsn'],
            'platformId' => $this->config['platformId'],
            'reason'     => $order['exceptReason'] ? $order['exceptReason'] : "人工运营处理售后退款",
            "appKey"     => $this->config['appKey'],
            "version"    => $this->config['version'],
            "timestamp"  => date("Y-m-d H:i:s", time()),
            "method"     => $this->RouteMap["createOrder"],
        ];
        $requestParam = [
            'method' => 'cancelOrder',
            'data'   => $data
        ];
        return $this->execute($requestParam);
    }

    /**
     * 加签
     * @param array $param
     */
    protected function getToken($param) {
        ini_set('serialize_precision', 14);
        $paramString = "";
        //过滤掉空值
        array_filter($param);
        //键名升序排序
        ksort($param);
        //md5(密钥+字符串+密钥),并转为大写；
        foreach ($param as $k => $v) {
            if($k == "sign"){
                continue;
            }
            if (is_array($v)) {
                $v = json_encode($v, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            }
            if ( $v != null && $v != "") {
                $paramString .= $k . $v;
            }
        }
        $app_secret = $this->config["app_secret"];
        return strtoupper(md5($app_secret . $paramString . $app_secret));
    }

    /**
     * CURL请求
     * @param $params
     * @return array
     */
    public function execute($param = []) {
        if (empty($param['data'])) {
            return Normal::returnCode(Normal::FAIL, "数据不能为空");
        }
        $method                = $param['method'];
        $url                   = $this->config['baseurl'] . "?method=" . $this->RouteMap[$method];
        $sign                  = $this->getToken($param['data']);
        $param['data']["sign"] = $sign;
        $parameter             = [
            [
                'tag'    => $this->account . '_' . $method,
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $url,
                'data'   => $param['data'],
                'method' => 'post',
                'format' => 'json',
                'header' => [
                    "Content-Type:application/json",
                ],
            ],
        ];
        $resTask               = TaskWorker::instance()->addTask($parameter);
        $resTask               = current($resTask);
        $res                   = $resTask['response']['result'];
        $resHttp               = @json_decode($res, true);
        if (isset($resHttp['status']) && $resHttp['status'] == 1) {
            return Normal::returnCode(Normal::SUC, "操作成功", $resHttp);
        }
        $message = isset($resHttp['note']) ? $resHttp['note'] : '请求失败';
        return Normal::returnCode(Normal::FAIL, $message);
    }
}